package com.lbssoft.gpsbd.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lbssoft.datalink.model.*;
import com.lbssoft.datalink.util.GISUtil;
import com.lbssoft.datalink.util.Log;
import com.lbssoft.gpsbd.common.Utils;
import com.lbssoft.gpsbd.controller.WebSocket;
import com.lbssoft.gpsbd.dao.DeviceMapper;
import com.lbssoft.gpsbd.dao.MediaMapper;
import com.lbssoft.gpsbd.dao.PositionMapper;
import com.lbssoft.gpsbd.dao.StatisticsStopMapper;
import com.lbssoft.gpsbd.datalink.Context;
import com.lbssoft.gpsbd.model.*;
import com.lbssoft.gpsbd.model.Event;
import com.lbssoft.gpsbd.model.Position;
import com.lbssoft.gpsbd.model.vo.PositionStatus;
import com.lbssoft.gpsbd.service.PositionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by Riven on 2018/7/19.
 */
@Service
public class PositionServiceImpl implements PositionService {

    @Autowired
    PositionMapper positionMapper;

    @Autowired
    DeviceMapper deviceMapper;

    @Autowired
    MediaMapper mediaMapper;

    @Autowired
    StatisticsStopMapper statisticsStopMapper;


    @Override
    public void add(Position position) {
        positionMapper.addPosition(position);
    }

    @Override
    public List<Position> getLastPositions() {
        return positionMapper.getLastPositions();
    }

    @Override
    public void updateLatestPosition(com.lbssoft.datalink.model.Position p) {
        Device dev = Context.deviceByUuid.get(p.getDeviceUUID());
        if(dev==null){
            Log.info("未知设备："+p.getUniqueId());
            return;
        }
        if(p.getLatitude()==0.0&&p.getLongitude()==0.0){
            Log.info("跳过无效位置："+p.getUniqueId());
            return;
        }
        //过滤未来的位置>当前时间10分钟
        if(p.getTime().getTime() > System.currentTimeMillis()+600000){
            Log.info(" 过滤未来的时间位置 "+p.getUniqueId());
            return;
        }
        Map<String,Object> lastAttributes = new HashMap<>();
        //判断是否有缓存位置
        if(Context.positions.get(dev.getId())!=null){
            lastAttributes =  (Map) JSONObject.parse(Context.positions.get(dev.getId()).getAttributes());
        }
        if(Context.positions.get(dev.getId())!=null&&p.getTime().compareTo(Context.positions.get(dev.getId()).getFixTime())>=0){
            //默认属性没有变化
            boolean flag = true;
            if (lastAttributes!=null&&!lastAttributes.equals("{}"))
                Log.info("lastAttributes "+lastAttributes);
                Log.info("p.getAttributes() "+p.getAttributes());
                flag = Utils.compareMap(lastAttributes, p.getAttributes());
                Log.info("flag "+flag);
                if(!lastAttributes.equals("{}")&&!flag){

                    if (p.getAttributes().containsKey("alarm")) {
                        if (!p.getAttributes().get("alarm").equals(lastAttributes.get("alarm"))) {
                            lastAttributes.put("alarm", p.getAttributes().get("alarm"));
                            //处理设备报警消息
                            Event event = new Event();
                            event.setDeviceId(dev.getId());
                            event.setId(dev.getId());
                            event.setType(9);
                            Map alarm = new HashMap();
                            alarm.put("alarm",p.getAttributes().get("alarm"));
                            event.setAttributes(JSON.toJSONString(alarm));

                            String address="";
                            Position position = positionMapper.getPositionByDeviceId(dev.getId());
                            try {
                                address = Utils.BaiduGeocoder(position.getLongitude(),position.getLatitude());
                            }catch (Exception e){

                            }
                            event.setPositionId(position.getId());
                            event.setAddress(address);
                            Context.dataManager.addAlarm(event);

                        }
                    } else {
                        lastAttributes.remove("alarm");
                    }

                    if (p.getAttributes().containsKey("image")) {
                        if (!p.getAttributes().get("image").equals(lastAttributes.get("image"))) {
                            lastAttributes.put("image", p.getAttributes().get("image"));
                            //处理照片信息
                            Media media = new Media();
                            media.setDeviceId(dev.getId());
                            media.setType("image");
                            media.setFile(p.getAttributes().get("image").toString());
                            mediaMapper.add(media);
                        }
                    }

                    if(p.getAttributes().containsKey("sat")&&!p.getAttributes().get("sat").equals(lastAttributes.get("sat"))){
                        lastAttributes.put("sat", p.getAttributes().get("sat"));
                    }
                    if(p.getAttributes().containsKey("ignition")&&!p.getAttributes().get("ignition").equals(lastAttributes.get("ignition"))){
                        lastAttributes.put("ignition", p.getAttributes().get("ignition"));
                    }
                    if(p.getAttributes().containsKey("rssi")&&!p.getAttributes().get("rssi").equals(lastAttributes.get("rssi"))){
                        lastAttributes.put("rssi", p.getAttributes().get("rssi"));
                    }
                    if(p.getAttributes().containsKey("battery")&&!p.getAttributes().get("battery").equals(lastAttributes.get("battery"))){
                        lastAttributes.put("battery", p.getAttributes().get("battery"));
                    }
                    if(p.getAttributes().containsKey("batteryLevel")&&!p.getAttributes().get("batteryLevel").equals(lastAttributes.get("battery"))){
                        lastAttributes.put("battery", p.getAttributes().get("batteryLevel"));
                    }

                    if(p.getAttributes().containsKey("fuelConsumption")&&!p.getAttributes().get("fuelConsumption").equals(lastAttributes.get("fuelc"))){
                        lastAttributes.put("fuelc", p.getAttributes().get("fuelConsumption"));
                    }
                    if(p.getAttributes().containsKey("defense")&&!p.getAttributes().get("defense").equals(lastAttributes.get("defense"))){
                        lastAttributes.put("defense", p.getAttributes().get("defense"));
                    }
                    if(p.getAttributes().containsKey("voltage")&&!p.getAttributes().get("voltage").equals(lastAttributes.get("voltage"))){
                        lastAttributes.put("voltage", p.getAttributes().get("voltage"));
                    }
                    if(p.getAttributes().containsKey("temp")&&!p.getAttributes().get("temp").equals(lastAttributes.get("temp"))){
                        lastAttributes.put("temp", p.getAttributes().get("temp"));
                    }
                    if(p.getAttributes().containsKey("temp0")&&!p.getAttributes().get("temp0").equals(lastAttributes.get("temp0"))){
                        lastAttributes.put("temp0", p.getAttributes().get("temp0"));
                    }
                    if(p.getAttributes().containsKey("temp1")&&!p.getAttributes().get("temp1").equals(lastAttributes.get("temp1"))){
                        lastAttributes.put("temp1", p.getAttributes().get("temp1"));
                    }
                    if(p.getAttributes().containsKey("temp2")&&!p.getAttributes().get("temp2").equals(lastAttributes.get("temp2"))){
                        lastAttributes.put("temp2", p.getAttributes().get("temp2"));
                    }
                    if(p.getAttributes().containsKey("temp3")&&!p.getAttributes().get("temp3").equals(lastAttributes.get("temp3"))){
                        lastAttributes.put("temp3", p.getAttributes().get("temp3"));
                    }
                    if(p.getAttributes().containsKey("turn")&&!p.getAttributes().get("turn").equals(lastAttributes.get("turn"))){
                        lastAttributes.put("turn", p.getAttributes().get("turn"));
                    }
                    if(p.getAttributes().containsKey("fuel")&&!p.getAttributes().get("fuel").equals(lastAttributes.get("fuel"))){
                        lastAttributes.put("fuel", p.getAttributes().get("fuel"));
                    }
                    if(p.getAttributes().containsKey("fuelPercentage")&&!p.getAttributes().get("fuelPercentage").equals(lastAttributes.get("fuelPercentage"))){
                        lastAttributes.put("fuelPercentage", p.getAttributes().get("fuelPercentage"));
                    }
                }
            if(flag&&Context.positions.get(dev.getId())!=null&&Context.positions.get(dev.getId()).getLatitude()==p.getLatitude()){
                Log.info("过滤重复记录："+p.getUniqueId());
                return;
            }


            //计算位置距离
            Position lastPositon = Context.positions.get(dev.getId());
            double distance = GISUtil.distance(lastPositon.getLatitude(), lastPositon.getLongitude(), p.getLatitude(), p.getLongitude()) / 1000;
            //if (distance > 0 && distance < 5 && p.getMode()==0) {
            if(lastAttributes.containsKey("trip")){
                BigDecimal bd = new BigDecimal(Double.parseDouble(lastAttributes.get("trip").toString())+distance);
                Double trip = bd.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                lastAttributes.put("trip", trip);
            }else{
                lastAttributes.put("trip", 0);
            }
            if(lastAttributes.containsKey("todaytrip")){
                BigDecimal bd2 = new BigDecimal(Double.parseDouble(lastAttributes.get("todaytrip").toString())+distance);
                Double todaytrip = bd2.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                lastAttributes.put("todaytrip", todaytrip);
            }else{
                lastAttributes.put("todaytrip", 0);
            }

            //}

        }


        Position position = new Position();
        position.setDeviceId(dev.getId());
        position.setFixTime(p.getTime());
        position.setLatitude(p.getLatitude());
        position.setLongitude(p.getLongitude());
        position.setSpeed(p.getSpeed());
        position.setCourse(p.getCourse());
        position.setAccuracy(p.getAccuracy());
        position.setMode(p.getMode());
        position.setAttributes(JSON.toJSONString(lastAttributes));
        //写入轨迹
        positionMapper.addPosition(position);

        //更新设备最后位置点
        deviceMapper.updateLastPosition(position.getId(), dev.getId());






        PositionStatus positionStatus = new PositionStatus();
        positionStatus.setDeviceId(dev.getId());
        positionStatus.setAccuracy(p.getAccuracy());
        positionStatus.setCourse(p.getCourse());
        positionStatus.setLatitude(p.getLatitude());
        positionStatus.setLongitude(p.getLongitude());
        positionStatus.setMode(0);
        positionStatus.setSpeed(p.getSpeed());
        positionStatus.setTime(p.getTime());
        positionStatus.setAttributes(JSON.toJSONString(lastAttributes));

        Collection<PositionStatus> positionMsgs = new ArrayList<PositionStatus>();
        positionMsgs.add(positionStatus);
        SocketMsg socketMsg = new SocketMsg("positions",positionMsgs);

        for(WebSocket item : WebSocket.clients()){
            try {
                if(item.getUserId()== Context.userByDevice.get(dev.getId())){
                    item.sendMessage(socketMsg);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if(Context.positions.get(dev.getId())==null){
            Context.positions.put(dev.getId(), position);
            return;
        }

        //计算停留时间
        int interval = GISUtil.Interval(Context.positions.get(dev.getId()).getFixTime(), p.getTime());
        if (interval >= 300) {
            String address="";
            StatisticsStop statisticsStop = new StatisticsStop();
            statisticsStop.setDeviceId(dev.getId());
            statisticsStop.setLatitude(Context.positions.get(dev.getId()).getLatitude());
            statisticsStop.setLongitude(Context.positions.get(dev.getId()).getLongitude());
            statisticsStop.setStartTime(Context.positions.get(dev.getId()).getFixTime());
            statisticsStop.setEndTime(p.getTime());
            statisticsStop.setStopTime(interval);
            try {
                address = Utils.BaiduGeocoder(statisticsStop.getLongitude(),statisticsStop.getLatitude());
            }catch (Exception e){

            }
            statisticsStop.setAddress(address);
            statisticsStopMapper.add(statisticsStop);

        }


        //刷新缓存最后位置
        Context.positions.put(dev.getId(), position);
    }





}

